#ifndef SWD_H
#define SWD_H
#include"stm32f405xx.h"
#define SWDCLK_Shift (0u)
#define SWDIO_Shift  (1u)

#define SWCLK_MODE_OUT() {GPIOA->MODER &= ~(0x3u << (SWDCLK_Shift*2));GPIOA->MODER |= 0X1 << (SWDCLK_Shift*2);}
#define SWDIO_MODE_IN()  {GPIOA->MODER &= ~(0x3u << (SWDIO_Shift *2));GPIOA->MODER |= 0X0 << (SWDIO_Shift *2);}
#define SWDIO_MODE_OUT() {GPIOA->MODER &= ~(0x3u << (SWDIO_Shift *2));GPIOA->MODER |= 0X1 << (SWDIO_Shift *2);}



//-----------------------------------------------------------------------------
// ARM Debug Interface Constants
//-----------------------------------------------------------------------------
//----------------------------APSEL--------------------------------------------
#define AHB_AP      0x00
#define APB_AP      0x01
#define JTAG_AP     0x02
#define Cortex_M3   0x03
//-------------------------AHB-AP-----------------------------------------
#define CSW         0x00
#define TAR         0x04
#define DRW         0x0C
#define BD0         0x10
#define BD1         0x14
#define BD2         0x18
#define BD3         0x1C
#define CFG         0xF4
#define BASE        0xF8
#define DPIDR         0xFC
//-----------------------
#define AddrIncrementOff    (0u)
#define AddrIncrementSingle (1u)//transfer size is word type can be valid,increment size is 4
#define AddrIncrementPacked (2u)
#define AddrIncShift        (4u)

//-------------------
#define CSW_Byte            (0u)
#define CSW_HalfWord        (1u)
#define CSW_Word            (2u)
#define CSW_SizeShift       (0u)
//-------{Port,Type}---------
#define CSW_Port_Type       (0x23000000u)
// ARM CoreSight SWD-DP packet request values
#define SW_IDCODE_RD            0xA5
#define SW_ABORT_WR             0x81
#define SW_CTRLSTAT_RD          0x8D
#define SW_CTRLSTAT_WR          0xA9
#define SW_RESEND_RD            0x95
#define SW_SELECT_WR            0xB1
#define SW_RDBUFF_RD            0xBD

// ARM CoreSight SW-DP packet request masks
#define SW_REQ_PARK_START       0x81
#define SW_REQ_PARITY           0x20
#define SW_REQ_A32              0x18
#define SW_REQ_RnW              0x04
#define SW_REQ_APnDP            0x02

// ARM CoreSight SW-DP packet acknowledge values
#define SW_ACK_OK               0x1
#define SW_ACK_WAIT             0x2
#define SW_ACK_FAULT            0x4
#define SW_ACK_PARITY_ERR       0x8

// ARM CoreSight DAP command values
#define DAP_IDCODE_RD           0x02
#define DAP_ABORT_WR            0x00
#define DAP_CTRLSTAT_RD         0x06
#define DAP_CTRLSTAT_WR         0x04
#define DAP_SELECT_WR           0x08
#define DAP_RDBUFF_RD           0x0E

// ARM CoreSight DAP command masks
#define DAP_CMD_PACKED          0x80
#define DAP_CMD_A32             0x0C
#define DAP_CMD_RnW             0x02
#define DAP_CMD_APnDP           0x01
#define DAP_CMD_MASK            0x0F

extern volatile unsigned int swd_mutx_lock;
#define ADD_Mutx() {__asm("cpsid i");swd_mutx_lock++;__asm("cpsie i");}
#define Relase_Mutx() {__asm("cpsid i");swd_mutx_lock--;__asm("cpsie i");}

void SWD_Init(void);
void SWD_LineReset(void);
unsigned int DAP_Read(unsigned char cnt, unsigned char DAP_Addr, unsigned int * read_data);
unsigned int DAP_Write(unsigned char cnt, unsigned char DAP_Addr, unsigned int write_data);
unsigned int DP_Write(unsigned int addr,unsigned int data);
unsigned int DP_Read(unsigned int addr,unsigned int* data);
unsigned int AP_Write(unsigned int addr,unsigned int data);
unsigned int AP_Read(unsigned int addr,unsigned int* data);
void SWD_set(unsigned int arg);
void SWD_Sequence(void);
#endif